package top.xierongsheng.code.aspect.power;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import top.xierongsheng.code.R;
import top.xierongsheng.code.redis.RedisService;
import top.xierongsheng.user.model.SysResource;
import top.xierongsheng.user.model.SysRoleResource;
import top.xierongsheng.user.service.IResourceService;
import top.xierongsheng.user.service.IRoleResourceService;
import top.xierongsheng.user.service.IUserService;

import jakarta.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * 系统权限验证
 *
 * @auther 谢荣生
 * @datetime 2020/11/23 9:48
 */
@Slf4j
@Aspect
@Component
public class SystemAuthenticationAspect {

    @Autowired
    private IUserService userService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private IResourceService resourceService;

    @Autowired
    private IRoleResourceService roleResourceService;

    /**
     * 在所有有注解标记( @RequiresPermissions )的方法中切入
     *
     * @auther 谢荣生
     * @datetime 2020/11/20 9:08
     */
    @Pointcut("@annotation(requiresPermissions)")
    public void permissionsServer(RequiresPermissions requiresPermissions) {
    }

    @Around("permissionsServer(requiresPermissions)")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint, RequiresPermissions requiresPermissions) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = (HttpServletRequest) Objects.requireNonNull(attributes).getRequest();
        String userId = request.getHeader("userId");

        if (null == userId) {
            log.error("-----------    【鉴权失败】 接口报文头缺少用户id (#`O′)    -----------");
            return R.timeout();
        }

        //获取需要的权限
        String[] permissionsStr = requiresPermissions.value();

        //获取角色id
        String roleId = userService.getById(userId).getRoleId();

        for (String resource : permissionsStr) {
            SysResource sysResource = resourceService.getOne(new QueryWrapper<SysResource>().lambda().eq(SysResource::getPermission, resource));
            if (sysResource == null) {
                log.info("----------- 【查无权限】 啊咧！！查不到，接口注解标记错误了(可能权限标识前端改了)    -----------");
                return R.error("权限标识不存在");
            }
            String resourceId = sysResource.getId();
            SysRoleResource sysRoleResource = roleResourceService.getOne(new QueryWrapper<SysRoleResource>().lambda().eq(SysRoleResource::getResourceId, resourceId).eq(SysRoleResource::getRoleId, roleId));
            if (sysRoleResource == null) {
                log.info("----------- 【查无权限】 啊咧！！查不到，没有权限啊    -----------");
                return R.powererror();
            }
        }
        Object result = proceedingJoinPoint.proceed();
        return result;
    }
}
